package org.ycx.generator.code;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.velocity.VelocityContext;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.ycx.common.util.JdbcUtil;
import org.ycx.common.util.VelocityUtil;

import java.io.File;
import java.util.*;

import static org.ycx.common.util.StringUtil.lineToHump;

/**
 * Created by 杨 on 2017-07-06.
 */
public class ModelAndMapperGenerator {


    /**
     * mybatis generator Config 模板路径
     */

    private static String generatorConfig_vm = "/templates/vm/generatorConfig.vm";
    /**
     * IMapper 模板路径
     * 继承自动生成的Mapper文件，实现自动生成后不影响已经实现的代码逻辑
     */
    private static String iMapper_vm = "/templates/vm/mapper.vm";

    /**
     * 默认model,dao生成模块名称（用于模块化项目）
     */
    private static String daoSuffix = "-dao";
    private static String modelSuffix = "-common";


    /**
     * 当前支持mysql,Oracle
     *
     * @param jdbcClass
     * @param jdbcUrl
     * @param jdbcUser
     * @param jdbcPwd
     * @param database
     * @param module
     * @param table_prefix
     * @param package_name
     * @throws Exception
     */
    public static void generatorModelAndMapper(
            String jdbcClass,
            String jdbcUrl,
            String jdbcUser,
            String jdbcPwd,
            String database,
            String module,
            String table_prefix,
            String package_name) throws Exception {
        //初始化工作
        int initFinished = 1;
        String daoProjectName = module + daoSuffix;
        String modelProjectName = module + modelSuffix;
        if (initFinished > 0) {
            String basePath = System.getProperty("user.dir");
            String generatorConfigPath = System.getProperty("user.dir") + "/" + daoProjectName + "/src/main/resources/generatorConfig.xml";
            generatorConfig_vm = System.getProperty("user.dir") + "/" + daoProjectName + "/src/main/resources/templates/vm/generatorConfig.vm";
            if (basePath.endsWith(daoProjectName)) {
                generatorConfigPath = System.getProperty("user.dir") + "/src/main/resources/generatorConfig.xml";
                generatorConfig_vm = System.getProperty("user.dir") + "/src/main/resources/templates/vm/generatorConfig.vm";
            }
            String tablesSql = null;
            if (database == null) {
                //Oracle
                tablesSql = "SELECT table_name from user_tables WHERE TABLE_NAME LIKE '" + table_prefix + "%'";
            } else {
                //Mysql
                tablesSql = "SELECT table_name,AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = '" + database + "' AND table_name LIKE '" + table_prefix + "_%';";
            }

            tablesSql = "SELECT t.TABLE_NAME TABLE_NAME,c.COLUMN_NAME COLUMN_NAME,ts.AUTO_INCREMENT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS t,information_schema.TABLES AS ts,information_schema.KEY_COLUMN_USAGE AS c WHERE t.TABLE_NAME = ts.TABLE_NAME AND ts.TABLE_NAME  = c.TABLE_NAME AND t.CONSTRAINT_TYPE = 'PRIMARY KEY' and ts.table_schema = '" + database + "' AND ts.table_name LIKE '" + table_prefix + "_%' and ts.AUTO_INCREMENT is not null";

            System.out.println("========== 开始生成generatorConfig.xml文件 ==========");
            List<Map<String, Object>> tables = new ArrayList<Map<String, Object>>();
            Map<String, String> last_insert_id_tables = new HashMap<String, String>();
            try {
                VelocityContext context = new VelocityContext();
                Map<String, Object> table;
                // 查询定制前缀项目的所有表
                JdbcUtil jdbcUtil = new JdbcUtil(jdbcClass, jdbcUrl, jdbcUser, jdbcPwd);
                List<Map> result = jdbcUtil.selectByParams(tablesSql, null);
                for (Map map : result) {
                    System.out.println(map.get("TABLE_NAME"));
                    table = new HashMap<String, Object>();
                    table.put("table_name", map.get("TABLE_NAME"));
                    table.put("model_name", lineToHump(ObjectUtils.toString(map.get("TABLE_NAME"))));
                    if (map.get("AUTO_INCREMENT") != null) {
                        last_insert_id_tables.put((String) map.get("TABLE_NAME"), (String) map.get("COLUMN_NAME"));
                    }
                    tables.add(table);
                }
                jdbcUtil.release();
                context.put("tables", tables);
                context.put("generator_javaModelGenerator_targetPackage", package_name + ".dao.model");
                context.put("generator_sqlMapGenerator_targetPackage", package_name + ".dao.auto");
                context.put("generator_javaClientGenerator_targetPackage", package_name + ".dao.auto");

                context.put("targetProject", daoProjectName);
                context.put("targetProject_common", modelProjectName);
                context.put("targetProject_sqlMap", daoProjectName);
                context.put("generator_jdbc_password", jdbcPwd);
                context.put("last_insert_id_tables", last_insert_id_tables);
                VelocityUtil.generate(generatorConfig_vm, generatorConfigPath, context);

                System.out.println("========== 开始运行MybatisGenerator ==========");
                List<String> warnings = new ArrayList<String>();
                File configFile = new File(generatorConfigPath);
                ConfigurationParser cp = new ConfigurationParser(warnings);
                Configuration config = cp.parseConfiguration(configFile);
                DefaultShellCallback callback = new DefaultShellCallback(true);
                MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
                myBatisGenerator.generate(null);
                for (String warning : warnings) {
                    System.out.println(warning);
                }
                System.out.println("========== 结束运行MybatisGenerator ==========");
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("========== 结束生成generatorConfig.xml文件 ==========");

        } else {
            System.err.println("模板初始化错误");
        }

    }

    //存在，执行


    public static String getGeneratorConfig_vm() {
        return generatorConfig_vm;
    }

    public static void setGeneratorConfig_vm(String generatorConfig_vm) {
        ModelAndMapperGenerator.generatorConfig_vm = generatorConfig_vm;
    }

    public static String getiMapper_vm() {
        return iMapper_vm;
    }

    public static void setiMapper_vm(String iMapper_vm) {
        ModelAndMapperGenerator.iMapper_vm = iMapper_vm;
    }

    public static String getDaoSuffix() {
        return daoSuffix;
    }

    public static void setDaoSuffix(String daoSuffix) {
        ModelAndMapperGenerator.daoSuffix = daoSuffix;
    }

    public static String getModelSuffix() {
        return modelSuffix;
    }

    public static void setModelSuffix(String modelSuffix) {
        ModelAndMapperGenerator.modelSuffix = modelSuffix;
    }
}
